Shader "Unlit/UnlitPlanarShadow_Only"
{
    Properties
    {
        _BaseMap ("Example Texture", 2D) = "white" {}
        _BaseColor ("Example Colour", Color) = (0, 0.66, 0.73, 1)
        _GroundHeight ("Ground Height", Float) = 0
        _ShadowColor ("Shadow Color", Color) = (0, 0, 0, 0.3)
    }
    SubShader
    {
        Tags
        {
            "RenderPipeline"="UniversalPipeline"
            "RenderType"="Transparent"
            "Queue"="Transparent"
        }

        HLSLINCLUDE
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

        CBUFFER_START(UnityPerMaterial)
        float4 _BaseMap_ST;
        float4 _BaseColor;
        float4 _GroundHeight;
        float4 _ShadowColor;
        CBUFFER_END
        ENDHLSL

        Pass
        {
            Name "PlanarShadow"
            Tags
            {
                "LightMode" = "PlanarShadow"
            }
            
            // 引入模板用来解决模型拍扁后重叠区域的颜色叠加问题
            Stencil
            {
                Ref 0
                Comp equal
                Pass incrWrap
                Fail keep
                ZFail keep
            }
            
            Blend SrcAlpha OneMinusSrcAlpha
            ZWrite off
            Cull Off
            Offset -1, 0

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 4.5

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

            struct Attributes
            {
                float4 positionOS : POSITION;
            };

            struct Varyings
            {
                float4 positionCS : SV_POSITION;
                float4 color : COLOR;
            };

            TEXTURE2D(_BaseMap);
            SAMPLER(sampler_BaseMap);

            // 将模型空间的顶点转换到平面阴影的世界坐标
            float3 ShadowProjectPos(float4 vertPos)
            {
                float3 shadowPos;

                float3 worldPos = TransformObjectToWorld(vertPos.xyz);

                Light mainLight = GetMainLight();
                float3 lightDir = normalize(mainLight.direction);

                //地平线高度
                float groundHeight = _GroundHeight;
                shadowPos.y = min(worldPos.y, groundHeight);
                shadowPos.xz = worldPos.xz - lightDir.xz * max(0, worldPos.y - groundHeight) / lightDir.y;

                return shadowPos;
            }
            
            Varyings vert(Attributes input)
            {
                Varyings output;

                float3 shadowPos = ShadowProjectPos(input.positionOS);
                output.positionCS = TransformWorldToHClip(shadowPos);
                output.color = _ShadowColor;
                return output;
            }

            float4 frag(Varyings input) : SV_Target
            {
                return input.color;
            }
            ENDHLSL
        }
    }
}
